package com.faxsun.core.order.service.type;

import java.util.LinkedHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.broadleafcommerce.core.order.domain.Order;
import org.broadleafcommerce.core.order.service.type.OrderStatus;

/**
 * 订单内部状态
 * 
 * @author zhaoteng.song@faxsun.com
 *
 */
public class FSInternalOrderStatus {

	private static final Log LOG = LogFactory.getLog(FSInternalOrderStatus.class);

	private static final LinkedHashMap<String, FSInternalOrderStatus> TYPES = new LinkedHashMap<String, FSInternalOrderStatus>();

	/**
	 * Used to represent a completed {@link Order}. Note that this also means
	 * that the {@link Order} should have its {@link Order#getOrderNumber} set
	 */
	public static final FSInternalOrderStatus SUBMITTED = new FSInternalOrderStatus("SUBMITTED", "已提交");
	public static final FSInternalOrderStatus CANCELLED = new FSInternalOrderStatus("CANCELLED", "已取消");

	/**
	 * 已确认
	 */
	public static final FSInternalOrderStatus CONFIRMED = new FSInternalOrderStatus("CONFIRMED", "已受理");
	/**
	 * 已发货
	 */
	public static final FSInternalOrderStatus DELIVERY = new FSInternalOrderStatus("DELIVERY", "已发货");

	/**
	 * 已签收
	 */
	public static final FSInternalOrderStatus SINGED = new FSInternalOrderStatus("SIGNED", "已签收");

	/**
	 * 申请退货
	 */
	public static final FSInternalOrderStatus REFUND_REQUEST = new FSInternalOrderStatus("REFUND_REQUEST",
			"退货申请已提交");

	/**
	 * 退货处理中
	 */
	public static final FSInternalOrderStatus REFUND_PROCESSING = new FSInternalOrderStatus(
			"REFUND_PROCESSING", "退货处理中");

	/**
	 * 退货完成
	 */
	public static final FSInternalOrderStatus REFUND_COMPLETE = new FSInternalOrderStatus("REFUND_COMPLETE",
			"已退货");

	/**
	 * 支付失败
	 */
	public static final FSInternalOrderStatus PAYMENT_FAIL = new FSInternalOrderStatus("PAYMENT_FAIL", "支付失败");

	/**
	 * 支付中
	 */
	public static final FSInternalOrderStatus PAYMENT_IN_PROCESS = new FSInternalOrderStatus(
			"PAYMENT_IN_PROCESS", "支付处理中");

	/**
	 * 处理支付失败
	 */
	public static final FSInternalOrderStatus PAYMENT_PROCESS_FAIL = new FSInternalOrderStatus(
			"PAYMENT_PROCESS_FAIL", "处理支付失败");

	/**
	 * 支付成功
	 */
	public static final FSInternalOrderStatus PAYMENT_SUBMITTED = new FSInternalOrderStatus("PAYMENT_SUBMITTED",
			"支付中");

	/**
	 * 支付成功
	 */
	public static final FSInternalOrderStatus PAYMENT_SUCCESS = new FSInternalOrderStatus("PAYMENT_SUCCESS",
			"支付成功");

	/**
	 * Used when a CSR has locked a cart to act on behalf of a customer
	 */
	public static final FSInternalOrderStatus CSR_OWNED = new FSInternalOrderStatus("CSR_OWNED",
			"Owned by CSR");

	public static FSInternalOrderStatus getInstance(final String type) {
		return TYPES.get(type);
	}

	private String type;
	private String friendlyType;

	public FSInternalOrderStatus() {
		// do nothing
	}

	public FSInternalOrderStatus(final String type, final String friendlyType) {
		this.friendlyType = friendlyType;
		setType(type);
	}

	public String getType() {
		return type;
	}

	public String getFriendlyType() {
		return friendlyType;
	}

	private void setType(final String type) {
		this.type = type;
		if (!TYPES.containsKey(type)) {
			TYPES.put(type, this);
		}
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((type == null) ? 0 : type.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!getClass().isAssignableFrom(obj.getClass()))
			return false;
		FSInternalOrderStatus other = (FSInternalOrderStatus) obj;
		if (type == null) {
			if (other.type != null)
				return false;
		} else if (!type.equals(other.type))
			return false;
		return true;
	}

	/**
	 * 将订单状态转换为内部订单状态
	 * 
	 * @param status
	 * @return null if status is not expected;
	 */
	public FSInternalOrderStatus convertFromOrderStatus(OrderStatus status) {
		FSInternalOrderStatus state = null;

		if (status instanceof FSOrderStatus) {
			state = getInstance(status.getType());
		} else if (status instanceof OrderStatus) {
			LOG.error("Order status is a instance of OrderStatus NOT FSOrderStatus!!!");
		}

		return state;
	}
}
